/*
 * @(#)JavacClassBuilder.java 1.0 2009/12/01
 */
package stardust.core.java.compiler;


import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import stardust.core.io.IOUtils;


/**
 * <code>JavacClassBuilder</code> 类通过系统 JAVAC 命令编译源程序。
 * <p/>
 * @see InnerClassBuilder
 * @see AbstractClassBuilder
 * @see ClassBuilderFactory
 * @version 1.0, 2009/12/01
 * @author ChenChang
 */
public class JavacClassBuilder extends AbstractClassBuilder
{

  /**
   * 创建一个 <tt>JavacClassBuilder</tt> 对象。
   */
  public JavacClassBuilder()
  {
    this(IOUtils.getTemporarilyDirectory());
  }

  public JavacClassBuilder(File targetDirectory)
  {
    super(targetDirectory);
  }

  public boolean compile()
  {
    /*
     * 初始化 javac 参数。
     */
    Iterator<String> names = super.files.keySet().iterator();
    List<String> javacArgs = new ArrayList<String>();
    String className, classSource;
    String fileName;
    File file;

    while (names.hasNext())
    {
      className = names.next();
      classSource = super.files.get(className);
      fileName = this.classNameToFileName(className);
      file = new File(super.getClassesDirectory(), fileName);

      try
      {
        IOUtils.write(file, classSource.getBytes(), false);
      }
      catch(IOException e)
      {
        log.error(e, "无法执行编译，文件写入失败：", file.getAbsolutePath());
        return false;
      }
      javacArgs.add(fileName);
    }

    // 组合 javac 参数。
    javacArgs.addAll(0, super.args);

    /*
     * 启动 javac 命令编译。
     */
    Process p = null;

    if (super.files.size() > 0)
    {
      StringBuffer buffer = new StringBuffer();

      try
      {
        buffer.append("javac");

        for (int i = 0; i < javacArgs.size(); i++)
        {
          buffer.append(" \"").append(javacArgs.get(i)).append("\"");
        }

        /*
         * 设定工作目录，命令然后执行并等待 javac 进程结束。
         */
        p = Runtime.getRuntime().exec(buffer.toString(), null, super.getClassesDirectory());
        p.waitFor();
      }
      catch(Exception e)
      {
        log.error(e, "无法执行编译，执行参数：", buffer.toString());
        return false;
      }
    }

    /*
     * 判断 javac 执行结果。
     */
    if (p.exitValue() == 0)
    {
      log.trace("编译代码：", super.files);

      return true;
    }
    else
    {
      this.log.warning("无法编译代码：", super.files);

      return false;
    }
  }

  private String classNameToFileName(String className)
  {
    return className.replaceAll("\\.", "/") + ".java";
  }

}
